package com.world.cat.service.sys;

import com.world.cat.app.AppConstant;
import com.world.cat.dao.sys.RoleDao;
import com.world.cat.dao.sys.RoleMenuDao;
import com.world.cat.dao.sys.UserDao;
import com.world.cat.dao.sys.UserRoleDao;
import com.world.cat.enums.Platform;
import com.world.cat.model.sys.Role;
import com.world.cat.model.sys.RoleMenu;
import com.world.cat.model.sys.User;
import com.world.cat.model.sys.UserRole;
import com.world.common.pojo.Result;
import com.world.common.util.AES;
import com.world.common.util.CollectionUtil;
import com.world.common.util.SysUtil;
import com.world.core.dao.GenericRepository;
import com.world.core.dao.SimpleExpression;
import net.sf.json.JSONObject;
import org.apache.log4j.Logger;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

@Service
@Transactional
public class UserService extends BaseService<User> {
    private static final Logger logger = Logger.getLogger(UserService.class);

    public static Map<String, User> userMap = new ConcurrentHashMap<>();
    public static Map<String, User> usernameUserMap = new ConcurrentHashMap<>();

    @Resource
    private UserDao userDao;
    @Resource
    private UserRoleDao userRoleDao;
    @Resource
    private RoleDao roleDao;
    @Resource
    private RoleMenuDao roleMenuDao;
    @Resource
    private TokenInfoService tokenInfoService;

    @Override
    public GenericRepository getDao() {
        return userDao;
    }

    public Result login(String username, String password, Platform platform) {
        User user = userDao.findByUsername(username);
        password = AES.encrypt(password, AppConstant.encryptKey);
        if (user != null && user.getPassword().equals(password)) {
            String token = tokenInfoService.getToken(user.getId(), platform);
            return new Result(true, "成功", token);
        }
        return new Result(false, "用户名或密码不正确");
    }

    public User getByUsername(String username) {
        return userDao.findByUsername(username);
    }

    public void save(User user) {
        User userDb = userDao.save(user);
        UserService.userMap.put(userDb.getId(), userDb);
        UserService.usernameUserMap.put(userDb.getUsername(), userDb);
    }

    public Result save(Class clazz, String jsonParams) throws Exception {
        JSONObject jsonObject = JSONObject.fromObject(jsonParams);
        Result result = BaseService.validateJsonParams(clazz, jsonObject);
        if (!result.isSuccess()) {
            return result;
        }
        User entity = initObjectByJsonParams(clazz, jsonObject);
        if (SysUtil.isEmpty(entity.getId())) {
            User user = userDao.findByUsername(entity.getUsername());
            if (user != null) {
                return new Result(false, "用户名已经存在");
            }
            entity.setPassword(AES.encrypt(entity.getPassword(), AppConstant.encryptKey));
        }
        User tDb = (User) getDao().save(entity);
        UserService.userMap.put(tDb.getId(), tDb);
        UserService.usernameUserMap.put(tDb.getUsername(), tDb);
        return new Result(true, "成功", tDb);
    }
    
    public User findById(String id) {
        return userDao.findOne(id);
    }

    public void del(String[] ids) {
        List<User> users = userDao.findByIdIn(Arrays.asList(ids));
        userDao.delete(users);
        for (User user : users) {
            UserService.userMap.remove(user.getId());
            UserService.usernameUserMap.remove(user.getUsername());
        }
    }

    public Result modifyPassword(String username, String oldPassword, String newPassword, String rePassword) {
        User user = userDao.findByUsername(username);
        if (user == null) {
            return new Result(false, "用户不存在");
        }
        if (SysUtil.isEmpty(newPassword)) {
            return new Result(false, "新密码不能为空");
        }
        if (!newPassword.equals(rePassword)) {
            return new Result(false, "两次书写的密码不一致");
        }
        if (!user.getPassword().equals(oldPassword)) {
            return new Result(false, "原密码错误");
        } else {
            user.setPassword(newPassword);
            userDao.save(user);
        }

        return new Result(true, "密码修改成功");
    }

    public void initUserCache() {
        logger.info("初始化用户数据开始");
        List<User> users = userDao.findAll();
        if (CollectionUtil.isNotEmpty(users)) {
            for (User user : users) {
                userMap.put(user.getId(), user);
                usernameUserMap.put(user.getUsername(), user);
            }
        }
        logger.info("初始化用户数据结束");
    }

    public Result getUserRoles(String id) {
        if (SysUtil.isEmpty(id)) {
            return new Result(false, "用户不存在");
        }
        User user = userDao.getOne(id);
        if (user == null) {
            return new Result(false, "用户不存在");
        }
        List<Map<String, String>> roleMapList = new ArrayList<>();
        List<Role> roles = roleDao.findAll();
        List<UserRole> userRoles = userRoleDao.findByUserId(user.getId());
        Set<String> roleIdSet = new HashSet<>();
        if (CollectionUtil.isNotEmpty(userRoles)) {
            for (UserRole userRole : userRoles) {
                roleIdSet.add(userRole.getRoleId());
            }
        }
        if (CollectionUtil.isNotEmpty(roles)) {
            for (Role role : roles) {
                Map<String, String> map = new HashMap<>();
                map.put("id", role.getId());
                if (roleIdSet.contains(role.getId())) {
                    map.put("checked", "true");
                } else {
                    map.put("checked", "false");
                }
                map.put("roleKey", role.getRoleKey());
                map.put("roleName", role.getRoleName());
                roleMapList.add(map);
            }
        }

        return new Result(true, "", roleMapList);
    }

    public Page findHandlerPage(Class clazz, String jsonParams, Pageable pageable) throws Exception {
        List<SimpleExpression> expressionList = BaseService.getExpressionByJsonParams(clazz, jsonParams);
        expressionList.add(new SimpleExpression("username", "(select distinct u.username from User u,UserRole ur,Role r where u.id=ur.userId and ur.roleId=r.id and r.roleKey='ROLE_BUSI_HANDLER')", SimpleExpression.Operator.SUB_QUERY_IN));
        Page page = getDao().findByPage(expressionList, pageable);
        return page;
    }

    public void saveAvatar(String username, String avatarUrl) {
        User user = userDao.findByUsername(username);
        user.setAvatar(avatarUrl);
        userDao.save(user);
    }

    //获取一个用户拥有的所有菜单的id集合
    public Set<String> getUserMenuIds(String username) {
        Set<String> menuIds = new HashSet<>();
        User user = userDao.findByUsername(username);
        List<UserRole> userRoles = userRoleDao.findByUserId(user.getId());
        if (CollectionUtil.isNotEmpty(userRoles)) {
            Set<String> roleIds = new HashSet<>();
            for (UserRole userRole : userRoles) {
                roleIds.add(userRole.getRoleId());
            }
            List<RoleMenu> roleMenus = roleMenuDao.findByRoleIdIn(roleIds);
            if (CollectionUtil.isNotEmpty(roleMenus)) {
                for (RoleMenu roleMenu : roleMenus) {
                    menuIds.add(roleMenu.getMenuId());
                }
            }
        }
        return menuIds;
    }
}
